/*
 *  ssp.h
 *
 *  Copyright (C) 2003 Russell King, All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This driver supports the following PXA CPU/SSP ports:-
 *
 *       PXA250     SSP
 *       PXA255     SSP, NSSP
 *       PXA26x     SSP, NSSP, ASSP
 *       PXA27x     SSP1, SSP2, SSP3
 */

#ifndef SSP_H
#define SSP_H

#include "monahans.h"
#include "util.h"

#define	CKEN_SSP1	26	/* < SSP1 clock enable */
#define	CKEN_SSP2	27	/* < SSP2 clock enable */
#define	CKEN_SSP3	28	/* < SSP3 clock enable */

#define SSSR_BCE		(1 << 23)	/* Bit Count Error */
#define SSSR_CSS		(1 << 22)	/* Clock Synchronisation Status */
#define SSSR_TUR		(1 << 21)	/* Transmit FIFO Under Run */
#define SSSR_EOC		(1 << 20)	/* End Of Chain */
#define SSSR_TINT		(1 << 19)	/* Receiver Time-out Interrupt */
#define SSSR_PINT		(1 << 18)	/* Peripheral Trailing Byte Interrupt */

#define SSTO_P1		__REG(0x41000028)  /* SSP Port 1 Time Out Register */
#define SSPSP_P1	__REG(0x4100002C)  /* SSP Port 1 Programmable Serial Protocol */
#define SSTSA_P1	__REG(0x41000030)  /* SSP Port 1 Tx Timeslot Active */
#define SSRSA_P1	__REG(0x41000034)  /* SSP Port 1 Rx Timeslot Active */
#define SSTSS_P1	__REG(0x41000038)  /* SSP Port 1 Timeslot Status */
#define SSACD_P1	__REG(0x4100003C)  /* SSP Port 1 Audio Clock Divider */
#define SSCR0_P2	__REG(0x41700000)  /* SSP Port 2 Control Register 0 */
#define SSCR1_P2	__REG(0x41700004)  /* SSP Port 2 Control Register 1 */
#define SSSR_P2		__REG(0x41700008)  /* SSP Port 2 Status Register */
#define SSITR_P2		__REG(0x4170000C)  /* SSP Port 2 Interrupt Test Register */
#define SSDR_P2		__REG(0x41700010)  /* (Write / Read) SSP Port 2 Data Write Register/SSP Data Read Register */
#define SSTO_P2		__REG(0x41700028)  /* SSP Port 2 Time Out Register */
#define SSPSP_P2	__REG(0x4170002C)  /* SSP Port 2 Programmable Serial Protocol */
#define SSTSA_P2	__REG(0x41700030)  /* SSP Port 2 Tx Timeslot Active */
#define SSRSA_P2	__REG(0x41700034)  /* SSP Port 2 Rx Timeslot Active */
#define SSTSS_P2	__REG(0x41700038)  /* SSP Port 2 Timeslot Status */
#define SSACD_P2	__REG(0x4170003C)  /* SSP Port 2 Audio Clock Divider */
#define	SSACDD_P2	__REG(0x41700040)  /* SSP Port 2 Audio Clock Dither Divider Register */

#define SSCR0_P3	__REG(0x41900000)  /* SSP Port 3 Control Register 0 */
#define SSCR1_P3	__REG(0x41900004)  /* SSP Port 3 Control Register 1 */
#define SSSR_P3		__REG(0x41900008)  /* SSP Port 3 Status Register */
#define SSITR_P3		__REG(0x4190000C)  /* SSP Port 3 Interrupt Test Register */
#define SSDR_P3		__REG(0x41900010)  /* (Write / Read) SSP Port 3 Data Write Register/SSP Data Read Register */
#define SSTO_P3		__REG(0x41900028)  /* SSP Port 3 Time Out Register */
#define SSPSP_P3	__REG(0x4190002C)  /* SSP Port 3 Programmable Serial Protocol */
#define SSTSA_P3	__REG(0x41900030)  /* SSP Port 3 Tx Timeslot Active */
#define SSRSA_P3	__REG(0x41900034)  /* SSP Port 3 Rx Timeslot Active */
#define SSTSS_P3	__REG(0x41900038)  /* SSP Port 3 Timeslot Status */
#define SSACD_P3	__REG(0x4190003C)  /* SSP Port 3 Audio Clock Divider */
#define SSACDD_P3	__REG(0x41900040)  /* SSP Port 3 Audio Clock Dither Divider Register */

#define SSCR0_P4        __REG(0x41A00000)  /* SSP Port 4 Control Register 0 */
#define SSCR1_P4        __REG(0x41A00004)  /* SSP Port 4 Control Register 1 */
#define SSSR_P4         __REG(0x41A00008)  /* SSP Port 4 Status Register */
#define SSITR_P4        __REG(0x41A0000C)  /* SSP Port 4 Interrupt Test Register */
#define SSDR_P4         __REG(0x41A00010)  /* (Write / Read) SSP Port 4 Data Write Register/SSP Data Read Register */
#define SSTO_P4         __REG(0x41A00028)  /* SSP Port 4 Time Out Register */
#define SSPSP_P4        __REG(0x41A0002C)  /* SSP Port 4 Programmable Serial Protocol */
#define	SSTSA_P4	__REG(0x41A00030)  /* SSP Port 4 TX Time Slot Active Register */
#define	SSRSA_P4	__REG(0x41A00034)  /* SSP Port 4 RX Time Slot Active Register */
#define	SSTSS_P4	__REG(0x41A00038)  /* SSP Port 4 Time Slot Status Register */
#define	SSACD_P4	__REG(0x41A0003C)  /* SSP Port 4 Audio Clock Divider Register */
#define	SSACDD_P4	__REG(0x41A00040)  /* SSP Port 4 Audio Clock Dither Divider Register */

#define SSCR0_P1	__REG(0x41000000)  /* SSP Port 1 Control Register 0 */
#define SSCR1_P1	__REG(0x41000004)  /* SSP Port 1 Control Register 1 */
#define SSSR_P1		__REG(0x41000008)  /* SSP Port 1 Status Register */
#define SSITR_P1	       __REG(0x4100000C)  /* SSP Port 1 Interrupt Test Register */
#define SSDR_P1		__REG(0x41000010)  /* (Write / Read) SSP Port 1 Data Write Register/SSP Data Read Register */

#define SSCR0_P(x) (*(((x) == 1) ? &SSCR0_P1 : ((x) == 2) ? &SSCR0_P2 : ((x) == 3) ? &SSCR0_P3 : ((x) == 4) ? &SSCR0_P4 : NULL))
#define SSCR1_P(x) (*(((x) == 1) ? &SSCR1_P1 : ((x) == 2) ? &SSCR1_P2 : ((x) == 3) ? &SSCR1_P3 : ((x) == 4) ? &SSCR1_P4 : NULL))
#define SSSR_P(x) (*(((x) == 1) ? &SSSR_P1 : ((x) == 2) ? &SSSR_P2 : ((x) == 3) ? &SSSR_P3 : ((x) == 4) ? &SSSR_P4 : NULL))
#define SSITR_P(x) (*(((x) == 1) ? &SSITR_P1 : ((x) == 2) ? &SSITR_P2 : ((x) == 3) ? &SSITR_P3 : ((x) == 4) ? &SSITR_P4 : NULL))
#define SSDR_P(x) (*(((x) == 1) ? &SSDR_P1 : ((x) == 2) ? &SSDR_P2 : ((x) == 3) ? &SSDR_P3 : ((x) == 4) ? &SSDR_P4 : NULL))
#define SSTO_P(x) (*(((x) == 1) ? &SSTO_P1 : ((x) == 2) ? &SSTO_P2 : ((x) == 3) ? &SSTO_P3 : ((x) == 4) ? &SSTO_P4 : NULL))
#define SSPSP_P(x) (*(((x) == 1) ? &SSPSP_P1 : ((x) == 2) ? &SSPSP_P2 : ((x) == 3) ? &SSPSP_P3 : ((x) == 4) ? &SSPSP_P4 : NULL))
#define SSTSA_P(x) (*(((x) == 1) ? &SSTSA_P1 : ((x) == 2) ? &SSTSA_P2 : ((x) == 3) ? &SSTSA_P3 : ((x) == 4) ? &SSTSA_P4 : NULL))
#define SSRSA_P(x) (*(((x) == 1) ? &SSRSA_P1 : ((x) == 2) ? &SSRSA_P2 : ((x) == 3) ? &SSRSA_P3 : ((x) == 4) ? &SSRSA_P4 : NULL))
#define SSTSS_P(x) (*(((x) == 1) ? &SSTSS_P1 : ((x) == 2) ? &SSTSS_P2 : ((x) == 3) ? &SSTSS_P3 : ((x) == 4) ? &SSTSS_P4 : NULL))
#define SSACD_P(x) (*(((x) == 1) ? &SSACD_P1 : ((x) == 2) ? &SSACD_P2 : ((x) == 3) ? &SSACD_P3 : ((x) == 4) ? &SSACD_P4 : NULL))
#define SSACDD_P(x) (*(((x) == 2) ? &SSACDD_P2 : ((x) == 3) ? &SSACDD_P3 : ((x) == 4) ? &SSACDD_P4 : NULL))


#define SSSR_TNF	(1 << 2)	/* Transmit FIFO Not Full */
#define SSSR_RNE	(1 << 3)	/* Receive FIFO Not Empty */
#define SSSR_BSY	(1 << 4)	/* SSP Busy */
#define SSSR_TFS	(1 << 5)	/* Transmit FIFO Service Request */
#define SSSR_RFS	(1 << 6)	/* Receive FIFO Service Request */
#define SSSR_ROR	(1 << 7)	/* Receive FIFO Overrun */

#define SSCR0_TIM		(1 << 23)	/* Transmit FIFO Under Run Interrupt Mask */
#define SSCR0_RIM		(1 << 22)	/* Receive FIFO Over Run interrupt Mask */
#define SSCR0_NCS		(1 << 21)	/* Network Clock Select */
#define SSCR0_EDSS		(1 << 20)	/* Extended Data Size Select */

#define SSCR0_SSE	(1 << 7)	/* Synchronous Serial Port Enable */

/*
 * Core Clock
 */
#if 1
#define ACCR		__REG(0x41340000)	/* Application Subsystem Clock Configuration Register */
#define ACSR		__REG(0x41340004)	/* Application Subsystem Clock Status Register */
#define AICSR		__REG(0x41340008)	/* Application Subsystem Interrupt Control/Status Register */
#define CKENA		__REG(0x4134000C)	/* A Clock Enable Register */
#define CKENB		__REG(0x41340010)	/* B Clock Enable Register */
#define AC97_DIV	__REG(0x41340014)	/* AC97 clock divisor value register */
#define OSCC		__REG(0x41350000)	/* Oscillator Configuration Register */

#define OSCC_PEN	(1 << 11)

/* Clock Enable Register (CLKEN) Enum */
#define	CKEN_LCD	1	/* < LCD Clock Enable */
#define	CKEN_USBH	2	/* < USB host clock enable */
#define	CKEN_CAMERA	3	/* < Camera interface clock enable */
#define	CKEN_NAND	4	/* < NAND Flash Controller Clock Enable */

#define CKEN_MMC3	5	/* < MMC3 Clock Enable */

#define	CKEN_USB2	6	/* < USB 2.0 client clock enable. */

#define CKEN_GRAPHICS	42

#define	CKEN_DMC	8	/* < Dynamic Memory Controller clock enable */
#define	CKEN_SMC	9	/* < Static Memory Controller clock enable */
#define	CKEN_ISC	10	/* < Internal SRAM Controller clock enable */
#define	CKEN_BOOT	11	/* < Boot rom clock enable */
#define	CKEN_MMC1	12	/* < MMC1 Clock enable */
#define	CKEN_MMC2	13	/* < MMC2 clock enable */
#define	CKEN_KEYPAD	14	/* < Keypand Controller Clock Enable */
#define	CKEN_CIR	15	/* < Consumer IR Clock Enable */
#define	CKEN_USIM0	17	/* < USIM[0] Clock Enable */
#define	CKEN_USIM1	18	/* < USIM[1] Clock Enable */
#define	CKEN_TPM	19	/* < TPM clock enable */
#define	CKEN_UDC	20	/* < UDC clock enable */
#define	CKEN_BTUART	21	/* < BTUART clock enable */
#define	CKEN_FFUART	22	/* < FFUART clock enable */
#define	CKEN_STUART	23	/* < STUART clock enable */
#define	CKEN_AC97	24	/* < AC97 clock enable */
#define	CKEN_TOUCH	25	/* < Touch screen Interface Clock Enable */
#define	CKEN_SSP1	26	/* < SSP1 clock enable */
#define	CKEN_SSP2	27	/* < SSP2 clock enable */
#define	CKEN_SSP3	28	/* < SSP3 clock enable */
#define	CKEN_SSP4	29	/* < SSP4 clock enable */
#define	CKEN_MSL0	30	/* < MSL0 clock enable */

#define	CKEN_PWM0	32	/* < PWM[0] clock enable */
#define	CKEN_PWM1	33	/* < PWM[1] clock enable */
#define	CKEN_I2C	36	/* < I2C clock enable */
#define	CKEN_INTC	38	/* < Interrupt controller clock enable */
#define	CKEN_GPIO	39	/* < GPIO clock enable */
#define	CKEN_1WIRE	40	/* < 1-wire clock enable */
#define CKEN_HSIO2	41	/* < HSIO2 clock enable */

#define CKEN_MVED	43	/* < MVED clock enable */
#define	CKEN_MINI_IM	48	/* < Mini-IM */
#define	CKEN_MINI_LCD	49	/* < Mini LCD */

#endif
void pxa_set_cken(int clock, int enable);
/*
 * SSP initialisation flags
 */
#define SSP_NO_IRQ	0x1		/* don't register an irq handler in SSP driver */
//#define u32 unsigned int
//typedef unsigned int u32
struct ssp_state {
	u32	cr0;
	u32 cr1;
	u32 to;
	u32 psp;
};

struct ssp_dev {
	u32 port;
	u32 mode;
	u32 flags;
	u32 psp_flags;
	u32 speed;
	int irq;
};
void pxa_set_cken(int clock, int enable);

int ssp_write_word(struct ssp_dev *dev, u32 data);
int ssp_read_word(struct ssp_dev *dev, u32 *data);
int ssp_flush(struct ssp_dev *dev);
void ssp_enable(struct ssp_dev *dev);
void ssp_disable(struct ssp_dev *dev);
void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp);
void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp);
int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags);
int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed);
void ssp_exit(struct ssp_dev *dev);

#endif
